package com.jlt.baidu.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jlt.baidu.constant.BaiduConstant;
import com.jlt.baidu.dto.CustomExcelResponse;
import com.jlt.baidu.dto.CustomOcrResponse;
import com.jlt.baidu.dto.QrcodeResponse;

import lombok.extern.slf4j.Slf4j;

/**
 * 百度OCR的测试
 * 
 * @author 苹果
 * @date 2019/12/21
 */
@Slf4j
public class BaiduOCRUtil {
    // 可以实际集成redis的有效期 token30天有效，设置29天失效
    static String token = null;

    /**
     * 
     * 按照分类进行图片识别，一个分类可以多个模板，按照统一分类
     * 
     * @param imageUrl
     * @return
     */
    public static CustomOcrResponse ocrImageClassifier(String baseresult, int classId) {
        if (token == null) {
            token = getAuth();
        }
        String uri = BaiduConstant.OCR_TEMPLAT_URL + token;
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(uri);
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setRequestHeader("Accept", "application/json");
            method.setParameter("image", baseresult);
            method.setParameter("classifierId", classId + "");
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                String result = method.getResponseBodyAsString();
                JSONObject obj = JSON.parseObject(result);
                if (!obj.getString("error_code").equals("0")) {
                    throw new RuntimeException(result);
                }
                CustomOcrResponse jsonResult = JSON.parseObject(result, CustomOcrResponse.class);
                return jsonResult;
            }
        } catch (IOException e) {
            log.error("请求二维码识别接口错误：", e);
        }
        return null;
    }

    /**
     * 
     * 图片定制模板识别
     * 
     * @param imageUrl
     * @return
     */
    public static CustomOcrResponse ocrImageTemplate(String baseresult, String template) {
        if (token == null) {
            token = getAuth();
        }
        String uri = BaiduConstant.OCR_TEMPLAT_URL + token;
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(uri);
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setRequestHeader("Accept", "application/json");
            method.setParameter("image", baseresult);
            method.setParameter("templateSign", template);
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                String result = method.getResponseBodyAsString();
                JSONObject obj = JSON.parseObject(result);
                if (!obj.getString("error_code").equals("0")) {
                    throw new RuntimeException(result);
                }
                CustomOcrResponse jsonResult = JSON.parseObject(result, CustomOcrResponse.class);
                return jsonResult;
            }
        } catch (IOException e) {
            log.error("请求二维码识别接口错误：", e);
        }
        return null;
    }

    /**
     * 图片的表格识别效果，同步接口
     * 
     * @param baseresult
     */
    public static CustomExcelResponse ocrImageExcel(String baseresult) {
        if (token == null) {
            token = getAuth();
        }
        String uri = BaiduConstant.OCR_EXCEL_URL + token;
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(uri);
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setRequestHeader("Accept", "application/json");
            NameValuePair part = new NameValuePair("image", baseresult);
            NameValuePair part1 = new NameValuePair("table_border", "normal");
            method.setRequestBody(new NameValuePair[] {part, part1});
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                // getResponseBodyAsString 方法默认编码ISO-8859-1
                String result = new String(method.getResponseBodyAsString().getBytes("ISO-8859-1"), "utf-8");
                CustomExcelResponse jsonResult = JSON.parseObject(result, CustomExcelResponse.class);
                return jsonResult;
            }
        } catch (IOException e) {
            log.error("请求表格识别接口错误：", e);
        }
        return null;
    }

    /**
     * 图片的表格识别效果，异步请求接口
     * 
     * @param baseresult
     */
    public static String ocrImageExcelSyncReq(String baseresult) {
        if (token == null) {
            token = getAuth();
        }
        String uri = BaiduConstant.OCR_EXCEL_SYNC_REQ_URL + token;
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(uri);
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setRequestHeader("Accept", "application/json");
            NameValuePair part = new NameValuePair("image", baseresult);
            method.setRequestBody(new NameValuePair[] {part});
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                // getResponseBodyAsString 方法默认编码ISO-8859-1
                String result = new String(method.getResponseBodyAsString().getBytes("ISO-8859-1"), "utf-8");
                return result;
            }
        } catch (IOException e) {
            log.error("请求表格识别接口错误：", e);
        }
        return null;
    }

    /**
     * 图片的表格识别效果，异步接口，请求结果
     * 
     * @param baseresult
     */
    public static String ocrImageExcelSyncRes(String requestId) {
        if (token == null) {
            token = getAuth();
        }
        String uri = BaiduConstant.OCR_EXCEL_SYNC_RES_URL + token;
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(uri);
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setRequestHeader("Accept", "application/json");
            NameValuePair part = new NameValuePair("request_id", requestId);
            NameValuePair part1 = new NameValuePair("request_type", "json");
            method.setRequestBody(new NameValuePair[] {part, part1});
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                // getResponseBodyAsString 方法默认编码ISO-8859-1
                String result = new String(method.getResponseBodyAsString().getBytes("ISO-8859-1"), "utf-8");
                return result;
            }
        } catch (IOException e) {
            log.error("请求表格识别接口错误：", e);
        }
        return null;
    }

    /**
     * 图片的二维码和条形码
     * 
     * 要求base64编码和urlencode后大小不超过4M，最短边至少15px，最长边最大4096px 将图片base64 支持jpg/jpeg/png/bmp格式
     * 
     * @param baseresult
     */
    public static QrcodeResponse ocrImageQrcode(String baseresult) {
        if (token == null) {
            token = getAuth();
        }
        String uri = BaiduConstant.OCR_QRCODE_URL + token;
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(uri);
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.setRequestHeader("Accept", "application/json");
            NameValuePair part = new NameValuePair("image", baseresult);
            method.setRequestBody(new NameValuePair[] {part});
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                // getResponseBodyAsString 方法默认编码ISO-8859-1
                String result = new String(method.getResponseBodyAsString().getBytes("ISO-8859-1"), "utf-8");
                if (result.indexOf("error_code") > 0) {
                    throw new RuntimeException(result);
                }
                QrcodeResponse jsonResult = JSON.parseObject(result, QrcodeResponse.class);
                return jsonResult;
            }
        } catch (IOException e) {
            log.error("请求二维码识别接口错误：", e);
        }
        return null;
    }

    /**
     * 获取百度的token
     * 
     * @return
     */
    private static String getAuth() {
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
            // 1. grant_type为固定参数
            + "grant_type=client_credentials"
            // 2. 官网获取的 API Key
            + "&client_id=" + BaiduConstant.OCR_API_KEY
            // 3. 官网获取的 Secret Key
            + "&client_secret=" + BaiduConstant.OCR_SECRET_KEY;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection)realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            /**
             * 返回结果示例
             */
            System.err.println("result:" + result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String access_token = jsonObject.getString("access_token");
            return access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败！");
            e.printStackTrace(System.err);
        }
        return null;
    }

    /**
     * 将图片base64
     * 
     * @param images
     * @return
     */
    public static String GetImageBase64(String images) {
        // 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            // 获取工程相对路径 路径到工程名
            // String basePath = System.getProperty("user.dir");
            // System.out.println(basePath);
            // 利用资源获取文件，是取编译的文件路径
            // *******\target\classes\static\images\jingdong\23544b071d66fdeb4907335140b530a.jpg
            // File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + images);
            File file = new File(images);
            log.info("图片大小（KB）：" + file.length() / 1024);
            InputStream in = new FileInputStream(file);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String baseresult = new String(Base64.encodeBase64(data));
        log.info("base加密后大小（KB）：" + baseresult.length() / 1024);
        return baseresult;
    }
}
